package materials.result;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import materials.data.NeuronDataOutputMaterial;


/**
 * A Material which reference a Set of DataOutput to a LayerID 
 * @author Sheepy
 */
public class NetworkResultMaterial implements NetworkResultInterface {

	/**
	 * The Map with the Set's of the NeuronDataMaterial
	 */
	private Map<Integer,Set<NeuronDataOutputMaterial>> _map;

	/**
	 * Initialize the NetworkResultMaterial
	 */
	public NetworkResultMaterial() {
		_map = new HashMap<Integer, Set<NeuronDataOutputMaterial>>();
	}

	/**
	 * Adds a Set of DataOutputMaterial referenced to an ID which mean the Layer
	 * @param lastoutput Set of DataOutputMaterial
	 * @param id ID of the Layer the ResultSet should be Referenced to
	 * @require lastoutput != null
	 * @require id > 0
	 * @ensure _list.contains(lastoutput) == true
	 */
	public void add(Set<NeuronDataOutputMaterial> lastoutput, int id) {
		assert lastoutput != null : "Vorbedingung verletzt: lastoutput != null";
		assert id > 0 : "Vorbedingung verletzt: id > 0";
		_map.put(id, lastoutput);
		assert _map.containsValue(lastoutput) : "Vorbedingung verletzt: _list.contains(lastoutput)";
	}

	/**
	 * Returns a Specific Set of OutputMaterial to a Layer
	 * @require i > 0
	 * @param int ID of the Layer which the Set is referenced by
	 * @return Set<NeuronDataOutputMaterial> - A Set of NeuronDataOutputMaterial of the Layer
	 */
	public Set<NeuronDataOutputMaterial> getLayerResult(int i) {
		assert i > 0 : "Vorbedingung verletzt: i > 0";
		return _map.get(i);
	}

	/**
	 * Returns a printable String of the NetworkResult
	 * @return String[] - Each Entry of the Array contains the whole Information of one Layer
	 */
	public String[] getPrintable() {
		String[] erg = new String[_map.size()];
		for (int i = 1; i <= _map.size(); i++) {
			erg[(i - 1)] = "";
			for (NeuronDataOutputMaterial nodm : _map.get(i)) {
				erg[(i - 1)] = erg[(i - 1)] + "@ID:" + nodm.getID() + "-"
						+ nodm.getOutput() + "  ";
			}
		}
		return erg;
	}

	/**
	 * Returns a Result by the NeuronID
	 * @param id ID of the Material the Output should be given to
	 * @require id > 0
	 * @return double - Result referenced to a NeuronID
	 */
	public double getResultByID(int id) {
		double ret = 0;
		boolean brk = false;
		for (Set<NeuronDataOutputMaterial> ndom : _map.values()) {
			for (NeuronDataOutputMaterial no : ndom) {
				if (no.getID() == id) {
					ret = no.getOutput();
					brk = true;
					break;
				}
			}
			if (brk) {
				break;
			}
		}
		return ret;
	}

	/**
	 * Returns, how many Set's of NeuronDataOutputMaterial are in the NetworkResult
	 * @return int - Numbers of the Sets
	 */
	public int getSize() {
		return _map.size();
	}

}
